import {Component, useComponentsStore} from "../../stores/components.tsx";
import {useComponentConfigStore} from "../../stores/component-config.tsx";
import React, {createElement, useRef} from "react";
import {message} from "antd";
import {ActionConfig} from "../Setting/ActionModal.tsx";

const Preview = () => {
    const components = useComponentsStore((state) => state.components)
    const componentConfig = useComponentConfigStore((state) => state.componentConfig)

    const componentRefs = useRef<Record<string, any>>({})

    // 给组件添加事件
    function handleEvent(component: Component) {
        // 定义一个可接受任意属性的props对象
        const props: Record<string, any> = {};

        componentConfig[component.name].events?.forEach((event) => {
            const eventConfig = component.props[event.name];
            if (eventConfig) {
                props[event.name] = (...args:any[]) => {
                    // 执行事件配置中的每个动作
                    eventConfig?.actions?.forEach((action: ActionConfig) => {
                        // 跳转到指定的URL
                        if (action.type === 'goToLink') {
                            window.location.href = action.url;
                        }
                        // 显示消息事件
                        else if (action.type === 'showMessage') {
                            if (action.config.type === 'success') {
                                message.success(action.config.text);
                            } else if (action.config.type === 'error') {
                                message.error(action.config.text);
                            }
                        }
                        // 自定义JS事件
                        else if (action.type === 'customJS') {
                            const func = new Function('context', 'args',action.code);
                            func({
                                name: component.name,
                                props: component.props,
                                showMessage(content: string) {
                                    message.success(content)
                                }
                            },args);
                        }
                        // 调用其他组件的方法
                        else if(action.type === 'componentMethod') {
                            const component = componentRefs.current[action.config.componentId];
                            if (component) {
                                component[action.config.method]?.(...args);
                            }
                        }
                    })

                }
            }
        })
        return props;
    }

    const nameId = (item:Component)=>{
        return item?.name +"_" + item?.id.toString().slice(item?.id.toString().length-5,item?.id.toString().length)
    }

    const renderComponents = (components: Component[]): React.ReactNode => {
        return components.map((item) => {
            const config = componentConfig?.[item.name]
            if (!config?.prod) return null
           if(config.prod.$$typeof === Symbol.for('react.forward_ref')){
               return createElement(config.prod, {
                       key: item.id,
                       id: item.id,
                       name: item.props.name ? item.props.name: nameId(item),
                       styles: item.styles,
                       ref: (ref: Record<string, any>) => {
                           componentRefs.current[item.id] = ref
                       },
                       ...config.defaultProps,
                       ...item.props,
                       ...handleEvent(item)
                   },
                   renderComponents(item.children || []))
           }
            return createElement(config.prod, {
                    key: item.id,
                    id: item.id,
                    name: item.props.name ? item.props.name: nameId(item),
                    styles: item.styles,
                    ...config.defaultProps,
                    ...item.props,
                    ...handleEvent(item)
                },
                renderComponents(item.children || []))
        })

    }
    return (
        <div>
            {renderComponents(components)}
        </div>
    );
};

export default Preview;